﻿/*-----------------------------------------------------------------*/
; Podprogram: Konwersja liczby całkowitej lub naturalnej
;             na postać tekstową, o ew. zadanej szerokości,
;             z możliwością wstawienia kropki dziesiętnej
; Autor:   Klemens Czajka
; Data:    2025-07-16
; Argumenty:
;	B7 = Liczba Całkowita (Integer) lub Naturalna (bez znaku)
;	A  = format: '000000000t000ckkkkssss0000000+++++*****'
;	     t=0 - w B7 jest liczba -274877906944 .. +274877906943
;	     t=1 - w B7 jest liczba naturalna   0 ..  549755813887
;	     c=0 - przed kropką ma być cyfra, np. +0.23456789012
;	     c=1 - przed kropką zbędna cyfra, np. +.123456789012
;	     kkkk=0..12 -- pozycja kropki (liczba cyfr po kropce)
;		  (wartość ograniczana do maksymalnej dopuszczalnej)
;	     ssss=0..14 -- wymagana szerokość tekstu wynikowego
;		  (większe liczby będą szersze, ssss>=15 jak 14)
;	     +++++=znak liczby całkowitej nieujemnej: NU,SP,+
;		   znak liczby całkowitej ujemnej zawsze:   -
;	     *****=znak uzupełnienia do szerokości:   NU=SP,0,*
;		   (SP przed znakiem liczby;  0,*,itp. po znaku)
; Wywołanie:
;	SKS  NumText		;konwersja liczby B7 wg formatu A
; Wyniki:
;	(A,B7)	= dwa słowa tekstu wynikowego
;		  (w B7 może być tekst pusty, ale słowo niezerowe)
;	B1, B2	zniszczone, reszta odtworzona
; Uwagi:
;   ---	Używa komórek 0c17572, 0c17573, 0c17576, 0c17577
;	używanych przez program STAŁY
;   ---	Przed asemblacją należy ustawić wartość symbolu wskazującego
;	wymaganą wersję podprogramu:
;	NumTxtK EQU 0	;wersja bez możliwości wstawiania kropki
;	NumTxtK EQU 1	;wersja z możliwością wstawiania kropki
/*-----------------------------------------------------------------*/
    AIF ?NumTxtK	;Ustalenie wymaganej wersji podprogramu
      AIF	NumTxtK == 0
#ntVK	EQU 0		;Wersja bez możliwości wstawiania kropki
      AELIF	NumTxtK == 1
#ntVK	EQU 0x10	;Wersja z możliwością wstawiania kropki
      AELSE
#ntVK	EQU 0		;Wersja bez możliwości wstawiania kropki
	NOTA	0,'Nieprzewidywana wartość symbolu NumTxtK.
Przyjęto 0 - wersję podprogramu bez możliwości wstawiania kropki.'
      AFI
    AELSE
#ntVK	EQU 0		;Wersja bez możliwości wstawiania kropki
    AFI
	  
NumText	STOP 0..*+2		;ślad powrotu
#ntJe	DS	1
/*==>*/	B2 = A & 0xF		;szerokość ssss wyniku: 0..14, 15
	[#ntSz] = B2
    AIF #ntVK
	A  = A >>< 4		;A='****000000000t000ckkkkssss...'
	B1 = A & #ntVK		;bit c, czy bez cyfry przed kropką
	[#ntCK] = B1
	B1 = A & 0xF		;pozycja kkkk kropki: 0..12, 13..15
	A  = A >>< 7		;A='0+++++*****000000000t000ck...'
    AELSE
	A  = A >>< 11		;A='0+++++*****000000000t000ck...'
    AFI
	A & 2			;Ustalenie typu liczby
	SKNZ	#nt03		;gdy Nat
;
	[#ntIS] = |B7|		;gdy Int	
	B7			;liczba w B7 dodatnia czy ujemna
	SKNU	#nt01
	B7 = [#ntMi]	..#nt02	;Ujemna   - znak liczby: '-'
#nt01	B7 = A & [#ntMZ]	;Dodatnia - znak liczby +++++ z A
#nt02	[#ntZn] = B7	..#nt05	;znak liczby
;
#nt03	[#ntIS] = B7		;Liczba w B7 naturalna
	[#ntZn] = 0		;Nat lub Int dodatnie: bez znaku

; Przygotowanie pozostałych parametrów
#nt05	EQU *
	A  = A <<< 5		;znak uzupełnienia: NU=SP,'0','*'
	A  = A & [#ntMZ]
	SKNZ	#nt06
	A  = [#ntSP]		;zamiana NU na SP
#nt06	[#ntZU] = A
    AIF #ntVK
	A  = 12			;kontrola pozycji kropki
	B1 - A
	SKM	#nt07
	[#ntPK] = A		;pozycja kropki= 12 
	[#ntCK] = #ntCK	..#nt08	;<>0 --- bez cyfry przed kropką
#nt07	[#ntPK] = B1		;pozycja kropki= 0..11
#nt08	EQU *
    AFI
	[#ntTx]   = 0
	[#ntTx+1] = 0
	B2 = 0			;licznik znaków wyniku

; Obliczenie najmłodszej cyfry
    AIF #ntVK
#nt20	EQU *
    AFI
	A  = [#ntIS]
	A  = A >>> 2		;podzielenie liczby przez 4
	M=[#ntD4], M, A=A/M	;B7=2.5k2, A=A/2.5	k(38-2)
	A  = A >>> 2		;(zgubiona część ułamkowa)
#nt22	EQU *
	B7 = A			;nowy iloraz (część całkowita)
	A  = A << 3		;mnożenie go przez 10
	A  = A + B7
	A  = A + B7		;A =nowy iloraz*10
	A  = [#ntIS] - A	;reszta = stary - nowy*10
	A  = A <<< 17
	B1 = A - 10		;korygowanie za dużej reszty
	SKM	#nt23		;reszta była OK
	A  = [#ntJe]		;korygowanie za małego ilorazu
	B7 = A + B7	..#nt24	;iloraz skorygowany
#nt23	B1 = A			;reszta = cyfra

; Dopisanie obliczonej cyfry
#nt24	EQU *
	[#ntIS] = B7		;nowy iloraz
	SKLC B2++,++		;licznik znaków
	A  = [#ntTx]
	B7 = [#ntTx+1]
	AM = AM >> 5
	A  = A + [#ntCy+B1]
	[#ntTx]   = A
	[#ntTx+1] = B7
    AIF #ntVK
	B1 = A = [#ntPK]	;czy dostawić kropkę
	B2 - A
	SKW	#nt25		;nie, pozycja kropki minęła
	SKM	#nt20		;nie, jeszcze nie tu
	SKLC B2++,++		;tak
	A  = [#ntTx]
;	B7 = [#ntTx+1]		;zbędne - już jest w B7
	AM = AM >> 5
	A  = A + [#ntKr]
	[#ntTx]   = A
	[#ntTx+1] = B7
	[#ntCK]			;czy ma być cyfra przed kropką
	SKZ	#nt20		;gdy tak
#nt25	EQU *			;gdy nie
    AFI

; Obliczenie kolejnej cyfry
	A  = [#ntIS]
	SKZ	#nt30
	M=[#ntD4], M, A=A/M	;B7=10k4, A=A/10	k(38-4)
	A  = A >>> 4	..#nt22	;(zgubienie części ułamkowej)

; Dopisywanie znaku liczby i znaków uzupełnienia do szerokości
#nt30	EQU *
	[#ntZn]			;czy liczba ze znakiem
	SKZ	#nt31		;liczba bez znaku
	SKLC B2++,++		;doliczyć miejsce na znak liczby

; Uzupełnienie znakami różnymi od SP, np.: '0','*'
#nt31	EQU *
	A  = [#ntZU]
	A - [#ntSP]
	SKR	#nt32
	SKS  #ntUz

; Wstawienie znaku liczby przed liczbą
#nt32	EQU *
	[#ntZn]			;czy liczba ze znakiem
	SKZ	#nt33		;liczba bez znaku
	A  = [#ntTx]
;	B7 = [#ntTx+1]		;zbędne - już jest w B7
	AM = AM >> 5
	A  = A + [#ntZn]
	[#ntTx]   = A
;	[#ntTx+1] = B7		;zbędne - stale jest w B7

; Uzupełnienie z lewej znakami SP
#nt33	EQU *
	A  = [#ntZU]
	A - [#ntSP]
	SKNR	#nt34
	SKS  #ntUz

; Sformatowanie tekstu wynikowego
#nt34	EQU *
	A  = B2			;szerokość wyniku
	B1 = A - 7		;szerokość w drugim słowie
	SKD	#nt35
	B1 = 8		..#nt36	;zero znaków w drugim słowie
#nt35	B2 = 7			;szerokość w pierwszym słowie
#nt36	EQU *			;Wstawienie długości do słów
	A  = [#ntTx]
;	B7 = [#ntTx+1]		;zbędne - już jest w B7
	AM = AM >> 3		;A='....1234567' B7='.8901234...'
	A  = A >>< 18
	A  = A + B2
	A  = A >>< 17		;A='1234567.lll'
	[#ntTx] = A
	A  = B7			;A='.8901234...'
	A  = A >>< 21
	A  = A + B1
	A  = A >>< 17		;B7='8901234.lll' lub
	B7 = A			;B7='.......1...'
	A  = [#ntTx]	..NumText   ;powrót z podprogramu



; Dopełnianie tekstu znakami uzupełnienia
#ntUz	STOP 0..*+2		;ślad #ntUz
#ntMZ	DS	31k5		;maska znaku w A
/*==>*/	A  = [#ntSz]		;szerokość zadana: 0..15
	A - 14			;kontrola zadanej szerokości
	SKMR	#nt80		;szerokość OK: 0..14
	A  = 14			;korekta zadanej szerokości
#nt80	A  = A - B2		;wielkość wolnego miejsca
	SKND	#ntUz		;brak miejsca - nie dopełniać
	B2 = A + B2		;szerokość tekstu wynikowego
	B1 = A
	A  = [#ntTx]
;	B7 = [#ntTx+1]		;zbędne - już jest w B7
#nt81	SKLC B1--,++	..#nt82
	AM = AM >> 5
	A  = A + [#ntZU]..#nt81
#nt82 ;	[#ntTx+1] = B7		;zbędne - stale jest w B7
	[#ntTx]   = A	..#ntUz



;	stałe programu
#ntD4	DS	10k4	;=2.5k2
#ntSP	DS	0' 'k5
#ntMi	DS	0'-'k5
    AIF #ntVK
#ntKr	DS	0'.'k5
    AFI
#ntCy	DS	22k5 23k5 19k5 1k5 10k5 16k5 21k5 7k5 6k5 24k5

;	zmienne robocze
#ntZn	DS	0'-'k5		;znak liczby: '-',  NU,' ','+'
#ntZU	DS	0'0'k5		;znak uzupełnienia: NU=SP,'0','*'
    AIF #ntVK
#ntSz	DS	15k21		;wymagana szerokość wyniku
#ntCK	DS	1k17		;=0 --- ma być cyfra przed kropką
#ntPK	EQU	0c17573		;pozycja kropki k21
    AELSE
#ntSz	EQU	0c17573		;wymagana szerokość wyniku k21
    AFI
#ntIS	EQU	0c17572		;iloraz stary
#ntTx	EQU	0c17576		;pierwsze słowo tekstu wynikowego
	EQU	0c17577		;drugie   słowo tekstu wynikowego

	KONIEC
***
